# !/usr/bin/env python
# encoding: utf-8


"""
  @author: gaogao
  @file: InstGenSS_N7744C.py
  @time: 2022/2/22 15:33
  OMPM
  @desc:
"""
from ATS.instrumentDriver import InstGen

from utils.singleton_util import singleton


@singleton
class SS_N7744C(InstGen.SS):
    def __init__(self, name):
        super().__init__(name)

    def idn(self):
        return self.handler.ask("*IDN?")

    def preset(self):
        # self.handler.write("*cls")  # clear error
        # return self.handler.ask(":CONFigure:MEASurement:SETTing:PRESet")
        return self.handler.ask("SYST:PRES;*OPC?")

    def tigger_status(self, mode=2):
        """
        1 or NODEA: Is identical to a trigger at the Input Trigger Connector.
        2 or NODEB: Generates trigger at the Output Trigger Connector.
        :param mode:
        :return:
        """
        self.handler.write(f":TRIG {mode}")

    def set_trigger_input(self, trigger_response="SME"):
        """
        Sets the incoming trigger response and arms the module.
        :param trigger_response:
        :return:
        IGNore: Ignore incoming trigger.
        SMEasure:Start a single measurement. If a measurement function is active, see :SENSe[n]:FUNCtion:STATe on
                page 78, one sample is performed and the result is stored in the data array,
                :SENSe[n]:FUNCtion:RESult? on page 75.
        CMEasure:Start a complete measurement. If a measurement function is active, :SENSe[n]:FUNCtion:STATe on
                page 78, a complete measurement function is performed.
        MMEasure:Similar to CME, the first hardware trigger starts the function and if LOOP is not 1, then multiple
                functions will be performed without waiting for further triggers.
        PREtrigger: Defines how many samples are stored before trigger event. Not possible to use multiple cycles.
        THReshold: Similar to PRE, but the starting event is minimum and maximum threshold values. If you don't want
                    both limit, you can write NAN instead of number.
        """
        self.handler.write(f"TRIG1:INP {trigger_response}")

    def set_auto_gain(self, gain_value=0):
        """
        0 = Auto Gain Off.
        This is the position for best transient response.
        1 = Auto Gain On (Default)
        This is the Position for best dynamic.
        :param gain_value:
        :return:
        """
        self.handler.write(f"SENS1:POW:GAIN:AUTO {gain_value}")

    def set_power_range_auto(self, boolean=1):
        """
        Enables or disables automatic power ranging for the channel.
        :param boolean: • 0 or OFF: automatic ranging disabled
                        • 1 or ON: automatic ranging enabled
        :return:
        """
        self.handler.write(f":SENSe1:POWer:RANGe:AUTO {boolean}")

    def get_power_range(self):
        return self.handler.ask("SENS1:POW:RANG?")

    def set_power_range(self, power_range=-10):
        """
        Sets the power range for the channel.
        The range changes at 10 dBm intervals. The corresponding ranges for linear measurements (measurements in Watts) is
        given below:
        :param power_range:
            +10 dBm
            0 dBm
            -10 dBm
            -20 dBm
            -30 dBm
        :return:
        """
        self.handler.write(f"SENS1:POW:RANG {power_range}DBM")

    def set_power_wave_length(self, wave_length):
        """
        Sets the sensor wavelength.
        Frequent use of this command can conflict with the timing of autoranging in some configurations. Autorange can be disabled
        before and enabled after the command if needed.
        :param wave_length:
        :return:
        """
        self.handler.write(f"SENS1:POW:WAV {wave_length}nm")

    def set_points_average_time(self, points=20000, average_time=100):
        """
        Sets the number of data points and the averaging time for the logging data acquisition function.
        :param points:
        :param average_time:
        :return:
        """
        self.handler.write(f"SENS1:FUNC:PAR:LOGG {points},{average_time}US")

    def set_power_unit(self, unit=0):
        """
        设置n7744c的数据的单位
        :param unit:0:dbm;1:w
        :return:
        """
        self.handler.write(f":sens1:pow:unit {unit}")

    def get_func_state(self):
        """
        Returns the function mode and the status of the data acquisition function.
        :return:
        """
        return self.handler.ask("SENS1:FUNC:STAT?").strip()

    def get_array_data(self):
        """
        Returns the data array of the last data acquisition function.
        :return:
        """
        return self.handler.query_binary_values("SENS1:FUNC:RES?")

    def set_logging_state(self, state="STAR"):
        """
        Enables/Disables the logging, MinMax, or stability data acquisition function mode.
        • LOGGing: Logging data acquisition function
        • STABility: Stability data acquisition function
        • MINMax: MinMax data acquisition function
        • STOP: Stop data acquisition function
        • STARt: Start data acquisition function
        :param state:
        :return:
        """
        # if state:
        #     state_value = "STAR"
        # else:
        #     state_value = "STOP"
        self.handler.write(f"SENS1:FUNC:STAT LOGG,{state}")

    def set_power_atim(self, atim_value):
        self.handler.write(f":sens1:pow:atim {atim_value}")

    def _init_set(self):
        self.handler.write("*cls")  # clear error
        self.handler.write(f":sens1:pow:atim {self.plc}us")  # 积分时间ns/us/ms/s
        # self.inst.query(f":SENSe1:POWer:REFerence:STATe:RATio?")  # 分光比相关指令
        self.handler.write(f":sens1:pow:unit {self.power_unit}")  # 0dbm 1w
        self.handler.write(f":sens1:pow:wav {self.wavlength}nm")

    def init_channel_continous(self):
        self.handler.write("init1:cont 1")

    def get_power_value(self, channel=1):
        """
        Reads the current power meter value. It does not provide its own triggering and so must be used with either continuous
        software triggering or a directly preceding immediate software trigger.
        It returns the value the previous software trigger measured. Any subsequent FETCh command will return the same value, if
        there is no subsequent software trigger.
        :param channel:
        :return:
        """
        return self.handler.ask(f":FETCH{channel}:POW?")

    def read_power_value(self, channel=1):
        return self.handler.ask(f":READ{channel}: POWer?")
